﻿using System;
using System.Collections.Generic;
using ProteinInsightInterface;
using System.Windows.Forms;
using System.Text;
using System.Drawing;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace ProteinInsightPlugin
{
    public class MyPlugin :  MarshalByRefObject, IProteinInsightPlugin
    {
        public void Run(IProteinInsight ProteinInsight)
        {
            try
            {
                //    write plug in code here.
                //                 FormDialog dialog = new FormDialog();
                //                 dialog.Init(ProteinInsight);
                //                 dialog.ShowDialog();

                //  test16(ProteinInsight);
                //  test19(ProteinInsight);
                
                //  test22(ProteinInsight);

                MakeVirusCapsidAnimation(ProteinInsight);
                //  test23(ProteinInsight);

            }
            catch (Exception e)
            {
                ProteinInsight.Utility.OutputMsg(e.ToString());
            }
        }

        public String Name
        {
            get
            {
                return "ProteinInsight C# Plug-In Test";
            }
        }

        public void test22(IProteinInsight pi)
        {
            pi.Open("1a31");
            pi.SetSelect(false, false);

            IAtom atom1 = pi.PDBs[0].Chains[0].Atoms[0];
            atom1.Select = true;
            pi.AddVP(IProteinInsight.IDisplayStyle.SpaceFill);

            IChain chainA = pi.PDBs[0].Chains[0];
            pi.AddVP(chainA, IProteinInsight.IDisplayStyle.Stick);

        }

        public void MakeVirusCapsidAnimation(IProteinInsight pi)
        {
            //  setting.
            String pdbID = "2cse";        //  2cse
            //  form inner layer to outer layer.
            String[] chainID = new String[] { "1", "VW", "XYZ", "U", "ABCJKLPQRT", "DEFGHIMNOS" };
            //  각각 layer의 color
            List<Color> animationColors = new List<Color> { 
                        Color.FromArgb(255,0,0),
                        Color.FromArgb(0,255,0),
                        Color.FromArgb(0,0,255),
                        Color.FromArgb(255,255,0),
                        Color.FromArgb(0,255,255),
                        Color.FromArgb(255,0,255)  };

            int numAnimation = 300;     //  안으로 모이는 animation의 step 수

            String movieFilename = "Protein-" + pdbID + ".wmv";

            bool bMakeMovie = true;

            //  
            int numAnimationBlock = chainID.Length;
            DateTime timeBegin = DateTime.Now;

            DateTime tBegin = DateTime.Now;
            pi.Utility.OutputMsg(pdbID + " BeginTime: " + tBegin.ToString());

            pi.Utility.OutputMsg(pdbID + ": make movie begin");

            int numBioUnit = 0;

            for (int i = 0; i < numAnimationBlock ; i++)        //  6
            {
                if (i == 0)
                {
                    pi.Open(pdbID, new List<int>(), chainID[i]);
                    pi.DeleteVP(pi.VPs[pi.VPs.Count - 1]);  //  마지막 VP를 지운다.

                    pi.PDBs[0].ShowBioUnit();
                    numBioUnit = pi.PDBs.Count;
                }
                else
                {
                    pi.AddPDB(pdbID, new List<int>(), chainID[i]);
                    pi.DeleteVP(pi.VPs[pi.VPs.Count - 1]);  //  마지막 VP를 지운다.

                    pi.PDBs[numBioUnit * i].ShowBioUnit();
                }
            }

            pi.Utility.OutputMsgInStatusBar("Color Change");
            //  set color of VPs
            for (int i = 0; i < numAnimationBlock; i++)
            {
                pi.Utility.SetProgressInStatusBar((i * 100) / numAnimationBlock);
                for (int j = 0; j < numBioUnit; j++)
                {
                    int indexVP = i * numBioUnit + j;

                    pi.VPs[indexVP].Property.ColorScheme = IProperty.IColorScheme.SingleColor;
                    List<Color> colors = pi.VPs[indexVP].Property.CustomizeColors;
                    colors[0] = animationColors[i];
                    pi.VPs[indexVP].Property.CustomizeColors = colors;
                }
            }

            pi.Utility.OutputMsgInStatusBar("");
            pi.Utility.SetProgressInStatusBar(0);

            //  
            pi.Property.Ground.AutoSetHeight();
            pi.Property.Ground.Height -= 30.0f;
            pi.Property.Lights[0].Position = pi.Property.Lights[0].Position * 1.5F;
            pi.Property.Camera.Position = pi.Property.Camera.Position * 1.5f;

            float lenRadius = pi.SizeRadius * 1.5f;

            for (int i = 0; i < pi.PDBs.Count; i++)
            {
                pi.PDBs[i].AttatchBioUnit = false;
            }

            //  모두 hide
            int numVPs = pi.VPs.Count;
            for (int i = 0; i < numVPs; i++)
            {
                pi.VPs[i].Show = false;
            }

            pi.Movie.BeginMovie(movieFilename , 1280, 720, 30, IMovie.ICaptureSource.PI);

            Matrix RotY = Matrix.RotationY(0.01F);

            //  안으로 모이기.
            for (int iLoop = 0; iLoop < numAnimationBlock ; iLoop++)
            {
                int beginVP = numBioUnit*iLoop;
                int endVP = numBioUnit*(iLoop+1);

                Vector3[] vecCenter = new Vector3[pi.VPs.Count];
                for (int i = beginVP; i < endVP; i++)
                {
                    vecCenter[i] = Vector3.Normalize(pi.VPs[i].CenterTransformed);

                    pi.VPs[i].Move(vecCenter[i] * lenRadius);
                    pi.VPs[i].Show = true;
                }

                for (int count = 0; count < numAnimation; count++)
                {
                    for (int i = beginVP; i < endVP; i++)
                    {
                        pi.VPs[i].Move(-vecCenter[i] * (lenRadius / (float)numAnimation));
                    }

                    pi.Property.Camera.Position = Vector3.TransformCoordinate(pi.Property.Camera.Position, RotY);
                    if ( bMakeMovie == true )
                        pi.Movie.Capture(1);
                }
            }

            //  끝나고 조금 더 돈다.
            for (int count = 0; count < 314/4; count++)
            {
                pi.Property.Camera.Position = Vector3.TransformCoordinate(pi.Property.Camera.Position, RotY);
                if (bMakeMovie == true)
                    pi.Movie.Capture(1);
            }

            //  바깥으로 흟어지기
            for (int iLoop = numAnimationBlock-1; iLoop >= 0 ; iLoop--)
            {
                int beginVP = numBioUnit * iLoop;
                int endVP = numBioUnit * (iLoop + 1);

                Vector3[] vecCenter = new Vector3[pi.VPs.Count];
                for (int i = beginVP; i < endVP; i++)
                {
                    vecCenter[i] = Vector3.Normalize(pi.VPs[i].CenterTransformed);
                }

                for (int count = 0; count < numAnimation; count++)
                {
                    for (int i = beginVP; i < endVP; i++)
                    {
                        pi.VPs[i].Move(vecCenter[i] * (lenRadius / (float)numAnimation));
                    }

                    pi.Property.Camera.Position = Vector3.TransformCoordinate(pi.Property.Camera.Position, RotY);
                    if (bMakeMovie == true)
                        pi.Movie.Capture(1);
                }

                for (int i = beginVP; i < endVP; i++)
                {
                    pi.VPs[i].Show = false;
                }
            }

            //  끝나고 조금 더 돈다.
            for (int count = 0; count < 314 / 10; count++)
            {
                pi.Property.Camera.Position = Vector3.TransformCoordinate(pi.Property.Camera.Position, RotY);
                if (bMakeMovie == true)
                    pi.Movie.Capture(1);
            }

            pi.Movie.EndMovie();

            //  
            DateTime tEnd = DateTime.Now;
            pi.Utility.OutputMsg(pdbID + " EndTime: " + tEnd.ToString());

            TimeSpan timeDuration = tEnd.Subtract(tBegin);

            pi.Utility.OutputMsg(pdbID + " Processing time is " + timeDuration.ToString());
        }

        public void test20(IProteinInsight pi)
        {
            String pdbName = "1Ld4";        

            DateTime timeBegin = DateTime.Now;

            String pdbID = pdbName;

            DateTime tBegin = DateTime.Now;
            pi.Utility.OutputMsg(pdbID + " BeginTime: " + tBegin.ToString());

            pi.Utility.OutputMsg(pdbID + ": make movie begin");

            const int numBioUnit = 60;
            pi.Open(pdbID);
            pi.PDBs[0].ShowBioUnit();

            pi.AddPDB(pdbID);
            pi.PDBs[numBioUnit].ShowBioUnit();

            pi.AddPDB(pdbID);
            pi.PDBs[numBioUnit*2].ShowBioUnit();

            pi.Property.Ground.AutoSetHeight();
            pi.Property.Ground.Height -= 30.0f;
            pi.Property.Lights[0].Position = pi.Property.Lights[0].Position * 1.5F;
            pi.Property.Camera.Position = pi.Property.Camera.Position * 1.5f;

            float lenRadius = pi.SizeRadius * 1.5f;

            for (int i = 0; i < pi.PDBs.Count; i++)
            {
                pi.PDBs[i].AttatchBioUnit = false;
            }

            //  delete all VPs
            int numVPs = pi.VPs.Count;
            for (int i = 0; i < numVPs ; i++)
            {
                pi.DeleteVP(pi.VPs[0]);
            }

            for (int i = 0; i < numBioUnit; i++)
            {
                pi.AddVP(pi.PDBs[i].GetChains("ABCD"), IProteinInsight.IDisplayStyle.Surface);
            }

            int innerVPs = pi.VPs.Count;

            //  
            for (int i = numBioUnit; i < numBioUnit*2 ; i++)
            {
                pi.AddVP(pi.PDBs[i].GetChains("EFGHIJKL"), IProteinInsight.IDisplayStyle.Surface);
            }

            int midVPs = pi.VPs.Count;

            //  
            for (int i = numBioUnit * 2; i < numBioUnit*3 ; i++)
            {
                pi.AddVP(pi.PDBs[i].GetChains("MNOP"), IProteinInsight.IDisplayStyle.Surface);
            }

            int outerVPs = pi.VPs.Count;

            //  모두 hide
            for (int i = 0; i < outerVPs; i++)
            {
                pi.VPs[i].Show = false;
            }

            pi.Movie.BeginMovie("Protein-" + pdbID + ".wmv", 1280, 720, 30, IMovie.ICaptureSource.PI);

            //  inner
            int[] beginIndex = { 0,     innerVPs, midVPs };
            int[] endIndex = { innerVPs, midVPs , outerVPs };

            Matrix RotY = Matrix.RotationY(0.01F);

            for (int iLoop = 0; iLoop < 3; iLoop++)
            {
                int beginVP = beginIndex[iLoop];
                int endVP = endIndex[iLoop];

                Vector3[] vecCenter = new Vector3[pi.VPs.Count];
                for (int i = beginVP; i < endVP; i++)
                {
                    vecCenter[i] = Vector3.Normalize(pi.VPs[i].CenterTransformed);

                    pi.VPs[i].Show = true;
                    pi.VPs[i].Move(vecCenter[i] * lenRadius);
                }

                int numAnimation = 300;

                for (int count = 0; count < numAnimation; count++)
                {
                    for (int i = beginVP; i < endVP; i++)
                    {
                        pi.VPs[i].Move(-vecCenter[i] * (lenRadius / (float)numAnimation));
                    }

                    pi.Property.Camera.Position = Vector3.TransformCoordinate(pi.Property.Camera.Position, RotY);
                    pi.Movie.Capture(1);
                }
            }

            //  끝나고 조금 더 돈다.
            for (int count = 0; count < 314; count++)
            {
                pi.Property.Camera.Position = Vector3.TransformCoordinate(pi.Property.Camera.Position, RotY);
                pi.Movie.Capture(1);
            }

            pi.Movie.EndMovie();
            
            //  
            /*

            Vector3[] vecCenter = new Vector3[pi.VPs.Count];
            for (int i = 0; i < pi.VPs.Count; i++)
            {
                vecCenter[i] = Vector3.Normalize(pi.VPs[i].CenterTransformed);

                pi.VPs[i].Show = true;
                pi.VPs[i].Move(vecCenter[i] * lenRadius);
            }

            Matrix RotY = Matrix.RotationY(0.01F);
            int numAnimation = 300;

            pi.Movie.BeginMovie("Protein-" + pdbID + ".wmv", 800, 600, 30, IMovie.ICaptureSource.PI);
            for (int count = 0; count < numAnimation; count++)
            {
                for (int i = 0; i < pi.VPs.Count; i++)
                {
                    pi.VPs[i].Move(-vecCenter[i] * (lenRadius / (float)numAnimation));
                }

                pi.Property.Camera.Position = Vector3.TransformCoordinate(pi.Property.Camera.Position, RotY);
                pi.Movie.Capture(1);
            }

            //  끝나고 조금 더 돈다.
            for (int count = 0; count < 314; count++)
            {
                pi.Property.Camera.Position = Vector3.TransformCoordinate(pi.Property.Camera.Position, RotY);
                pi.Movie.Capture(1);
            }

            pi.Movie.EndMovie();
            */

            DateTime tEnd = DateTime.Now;
            pi.Utility.OutputMsg(pdbID + " EndTime: " + tEnd.ToString());

            TimeSpan timeDuration = tEnd.Subtract(tBegin);

            pi.Utility.OutputMsg(pdbID + " Processing time is " + timeDuration.ToString());
        }

        public void test19(IProteinInsight pi)
        {
                String[] pdbName = new String[8] { "3MUW", "3N09", "3IZG", "3N7X", "2XPJ", "2x5i", "3IYP", "3IYU" };

                DateTime timeBegin = DateTime.Now;

                for (int iPDB = 0; iPDB < 8; iPDB++)
                {
                    String pdbID = pdbName[iPDB];

                    DateTime tBegin = DateTime.Now;
                    pi.Utility.OutputMsg(pdbID + " BeginTime: " + tBegin.ToString());

                    pi.Utility.SetProgressInStatusBar((iPDB * 100) / 8);

                    pi.Utility.OutputMsg(pdbID + ": make movie begin");

                    pi.Open(pdbID);
                    pi.DeleteVP(pi.VPs[0]);

                    pi.PDBs[0].ShowBioUnit();

                    pi.Property.Ground.AutoSetHeight();
                    pi.Property.Ground.Height -= 30.0f;
                    pi.Property.Lights[0].Position = pi.Property.Lights[0].Position * 1.5F;
                    pi.Property.Camera.Position = pi.Property.Camera.Position * 1.5f;

                    float lenRadius = pi.SizeRadius * 1.5f;

                    for (int i = 0; i < pi.PDBs.Count; i++)
                    {
                        pi.PDBs[i].AttatchBioUnit = false;
                    }

                    Vector3[] vecCenter = new Vector3[pi.VPs.Count];
                    for (int i = 0; i < pi.VPs.Count; i++)
                    {
                        vecCenter[i] = Vector3.Normalize(pi.VPs[i].CenterTransformed);

                        pi.VPs[i].Show = true;
                        pi.VPs[i].Move(vecCenter[i] * lenRadius);
                    }

                    Matrix RotY = Matrix.RotationY(0.01F);
                    int numAnimation = 300;
                    
                    pi.Movie.BeginMovie("Protein-" + pdbID + ".wmv", 800, 600, 30, IMovie.ICaptureSource.PI);
                    for (int count = 0; count < numAnimation; count++)
                    {
                        for (int i = 0; i < pi.VPs.Count; i++)
                        {
                            pi.VPs[i].Move(-vecCenter[i] * (lenRadius / (float)numAnimation));
                        }

                        pi.Property.Camera.Position = Vector3.TransformCoordinate(pi.Property.Camera.Position, RotY);
                        pi.Movie.Capture(1);
                    }

                    //  끝나고 조금 더 돈다.
                    for (int count = 0; count < 314; count++)
                    {
                        pi.Property.Camera.Position = Vector3.TransformCoordinate(pi.Property.Camera.Position, RotY);
                        pi.Movie.Capture(1);
                    }

                    pi.Movie.EndMovie();

                    DateTime tEnd = DateTime.Now;
                    pi.Utility.OutputMsg(pdbID + " EndTime: " + tEnd.ToString());

                    TimeSpan timeDuration = tEnd.Subtract(tBegin);

                    pi.Utility.OutputMsg(pdbID + " Processing time is " + timeDuration.ToString());
                }
        }

        public void test18(IProteinInsight PI)
        {
            PI.Open("1a6d");
            PI.PDBs[0].ShowBioUnit();

            for (float p = 0; p < 30; p += 1.0f)
            {
                for (int i = 0; i < PI.VPs.Count; i++)
                    PI.VPs[i].Move(0.1f, 0.1f, 0.1f);
            }

            //             IVP vp = PI.VPs[0];
            //             for (float p = 0; p < 100; p += 1.0f)
            //                 vp.Move(p, p, p);
            
        }

        public void test17(IProteinInsight PI)
        {

            //    write plug in script code here.
            for ( int i = 0 ; i < PI.VPs.Count ; i++ )
            {
                IVP vp = PI.VPs[i];
                vp.Property.ColorScheme = IProperty.IColorScheme.SingleColor;
                List<Color> colors = vp.Property.CustomizeColors;
                colors[0] = PI.Utility.GetGradientColor(i, PI.VPs.Count);
                vp.Property.CustomizeColors = colors;
            }


        				PI.Open("1NME");	

                //	Set VP1 as ribbon visualization of Chain A
                IVP VP1 = PI.AddVP(PI.PDBs[0].GetChains("A"), IProteinInsight.IDisplayStyle.Ribbon);		
                //	Set VP2 as ball&stick visualization of Chain B
                IVP VP2 = PI.AddVP(PI.PDBs[0].GetChains("B"), IProteinInsight.IDisplayStyle.BallnStick);	

                //	Change Helix color to red
                VP1.PropertyRibbon.Helix.Color = Color.Red;				
                //	Change color scheme to residue color scheme
                VP2.Property.ColorScheme = IProperty.IColorScheme.Residue;		

                //	rotate camera in the world space
                for (Double degree = 0; degree < 360.0f; degree += 5.0)			
                {
	                Double xPos = 100.0 * Math.Cos(Math.PI * degree / 180.0);
	                Double zPos = 100.0 * Math.Sin(Math.PI * degree / 180.0);
	                PI.Property.Camera.Position = new Vector3((float)xPos, 0, (float)zPos);
	                PI.Idle(10);
                }

                //	Make screen image to "1NME.png"
                PI.SaveImage("1NME.png", 800, 600, IProteinInsight.IImageFormat.PNG);	
        }

        public void test6(IProteinInsight ProteinInsight)
        {
            //    Set movie recording, filename is "rotation.wmv", size is 800x600, frame rate is 10
            //  ProteinInsight.Movie.BeginMovie("rotation.wmv", 800, 600, 10, IMovie.ICaptureSource.PI );

            //ProteinInsight.Open("SmallProtein.ent");
            //ProteinInsight.Property.BackgroundColor = Color.White;
            //ProteinInsight.Property.ShowBackgroundTexture = false;
            //ProteinInsight.Property.ShowSelectionMark = false;

            //  ProteinInsight.DeleteVP(ProteinInsight.VPs[0]);

            //  IVP vp = ProteinInsight.AddVP(ProteinInsight.PDBs[0].Chains[0], IProteinInsight.IDisplayStyle.Ribbon);
            //  vp.MoveCenter();

            IVP vp = ProteinInsight.VPs[0];

            for (int i = 0; i < 360; i ++ )
            {
                vp.Move(0.1f, 0.0f, 0.0f);
                //  vp.RotationY((float)((1 / 360.0f) * 2 * 3.14));
                //  vp.RotationX((float)((1 / 360.0f) * 2 * 3.14));
                //    //  ProteinInsight.Movie.Capture(1);        //    capture 2 frame in current screen
                ProteinInsight.Idle(10);
            }
            //    save movie
            //  ProteinInsight.Movie.EndMovie();
        }


        public void test16(IProteinInsight PI)
        {
            //  PI.VPUnionVP(PI.VPs[0], PI.VPs[3]);
            //  PI.AddVP(IProteinInsight.IDisplayStyle.SpaceFill);

				//    write plug in script code here.
				PI.VPs[0].Property.AnnotationAtom.Show  = true;
				PI.VPs[0].Property.AnnotationAtom.FontName = "Lucida2";
				PI.VPs[0].Property.AnnotationAtom.FontHeight  = 25;

				int height = PI.VPs[0].Property.AnnotationAtom.FontHeight;
				height ++;
                PI.VPs[0].Property.AnnotationAtom.FontHeight = height;

                //
                PI.VPs[0].Property.DisplaySideChain = false;

                IVP vp = PI.VPs[0];
				vp.Property.ColorScheme = IProperty.IColorScheme.Progressive;

                List<Color> colors = PI.VPs[0].Property.CustomizeColors;
                colors[0] = Color.FromArgb(255, 255, 0);
                colors[1] = Color.FromArgb(255, 255, 255);
                colors.Add(Color.FromArgb(255, 0, 255));
                PI.VPs[0].Property.CustomizeColors = colors;

                PI.VPs[0].PropertyRibbon.SelectInnerAtomsInDNA();
                PI.AddVP(IProteinInsight.IDisplayStyle.BallnStick);
        }

        public void test15(IProteinInsight ProteinInsight)
        {

            ProteinInsight.Open("1NME");

            IVP vp1 = ProteinInsight.AddVP(ProteinInsight.PDBs[0].Chains[0], IProteinInsight.IDisplayStyle.Ribbon);
            
            Matrix mat = vp1.TransformLocal;
            mat.M41 += 100;
            mat.M42 += 100;
            mat.M43 += 100;
            vp1.TransformLocal = mat;

            //  Microsoft.DirectX.Direct3D.Device device = ProteinInsight.GetDirect3DDevice9();
            //  device.SetRenderState(Microsoft.DirectX.Direct3D.RenderStates.FillMode, 2);
        }

        public void test14(IProteinInsight ProteinInsight)
        {
            ProteinInsight.Open("1NME");
            ProteinInsight.AddPDB("1A31");

            IPDB pdb1 = ProteinInsight.PDBs[0];
            IPDB pdb2 = ProteinInsight.PDBs[1];

            ProteinInsight.ClosePDB(pdb1);
            
            IVP vp1 = ProteinInsight.AddVP(pdb1, IProteinInsight.IDisplayStyle.SpaceFill);
            IVP vp2 = ProteinInsight.AddVP(pdb2, IProteinInsight.IDisplayStyle.Ribbon);

            vp2.Show = false;
            ProteinInsight.SaveImage("1NME", 1280, 1024, IProteinInsight.IImageFormat.PNG);
            vp2.Show = true;
            vp1.Show = false;

            ProteinInsight.SaveImage("1A31", 1280, 1024, IProteinInsight.IImageFormat.PNG);
        }

        public void test13(IProteinInsight ProteinInsight)
        {
            List<IPDB> pdbs = ProteinInsight.PDBs;
            //  ProteinInsight.VPs

            IVP vp1 = ProteinInsight.AddVP(ProteinInsight.PDBs[0].GetChains("A"), IProteinInsight.IDisplayStyle.Surface);
            vp1.PropertyRibbon.Helix.Show = true;
            vp1.PropertyRibbon.Sheet.Size = new Size(10, 10);
            vp1.PropertyRibbon.Coil.ShowTexture = false;
            //Size s = vp1.PropertyRibbon.Sheet.Size;
            //s.Width = s.Height = 100;

            ////  vp1.PropertyRibbon.Sheet.Size.Height = 30;


        }

        public void test1(IProteinInsight ProteinInsight)
        {
            IVP vp1 = ProteinInsight.AddVP(ProteinInsight.PDBs[0].GetChains("A"), IProteinInsight.IDisplayStyle.Surface);
            vp1.Property.ColorScheme = IProperty.IColorScheme.Residue;
            vp1.Property.ColorScheme = IProperty.IColorScheme.CPK;
            ProteinInsight.Idle(2000);								//	pause 2 sec(2000 millisec)
            vp1.Property.ColorScheme = IProperty.IColorScheme.Residue;
            ProteinInsight.Idle(2000);
            vp1.Property.ColorScheme = IProperty.IColorScheme.Chain;


            ProteinInsight.SetSelect(false, true);

            //  enumeration from PDBs to atoms.
            foreach (IPDB pdb in ProteinInsight.PDBs)
                foreach (IModel model in pdb.Models)
                    foreach (IChain chain in model.Chains)
                        foreach (IResidue residue in chain.Residues)
                            foreach (IAtom atom in residue.Atoms)
                            {
                                String strMsg = String.Format("Atom Position: {0:s}", atom.Position.ToString());
                                ProteinInsight.Utility.OutputMsg(strMsg);
                            }

        }

        public void test3(IProteinInsight ProteinInsight)
        {
            foreach (IResidue r in ProteinInsight.PDBs[0].Chains[0].GetSSResidues(IResidue.ISSType.Helix) )
                    r.SetSelect(true, true);
            ProteinInsight.AddVP(ProteinInsight.PDBs[0].Chains[0].GetSSResidues(IResidue.ISSType.Helix), IProteinInsight.IDisplayStyle.Surface);
                                    
            IPDB pdb = ProteinInsight.PDBs[0];
            for (int i = 0; i < pdb.Chains.Count; i++)
            {
                String strMsg = String.Format("PDB ID:{0:s}, Chain ID:{1:s}\n", pdb.Chains[i].PDBID, pdb.Chains[i].ID);
                ProteinInsight.Utility.OutputMsg(strMsg);
            }

            IChain Chain = ProteinInsight.PDBs[0].Chains[0];
            for (int i = 0; i < Chain.Residues.Count; i++)
            {
                IResidue residue = Chain.Residues[i];

                for ( int j = 0 ; j < residue.Atoms.Count ; j++ )
                {
                    ProteinInsight.Utility.OutputMsg(residue.Atoms[j].Name);
                }


                //	find Helix residue.
                //if (Chain.Residues[i].SSType == IResidue.ISSType.Helix)
                //    if (Chain.Residues[i].HelixType == IResidue.IHelixType.PI)
                //        Chain.Residues[i].SetSelect(true, true);
            }
            //	Show selected atoms
            ProteinInsight.AddVP(IProteinInsight.IDisplayStyle.SpaceFill);
        }

        public void test2(IProteinInsight ProteinInsight)
        {
            ProteinInsight.SetSelect(false, true);

            IChain Chain = ProteinInsight.PDBs[0].Chains[0];
            for (int i = 0; i < Chain.Atoms.Count; i++)
            {
                if (Chain.Atoms[i].Type == IAtom.IType.CA)
                    Chain.Atoms[i].SetSelect(true, true);
            }

            ProteinInsight.AddVP(IProteinInsight.IDisplayStyle.SpaceFill);

        }

        public void test4(IProteinInsight ProteinInsight)
        {
            IAtom Atom1 = ProteinInsight.PDBs[0].Chains[0].Residues[0].Atoms[0];
            IAtom Atom2 = ProteinInsight.PDBs[0].GetChains("A")[0].Atoms[0];

            ProteinInsight.Utility.OutputMsg(Atom1.Position.ToString());

            ProteinInsight.Open("1NME");
            ProteinInsight.Property.RenderQuality.Shader = IRenderQuality.IShader.High;
            ProteinInsight.Property.RenderQuality.Geometry = IRenderQuality.IGeometry.High;

            IVP VP1 = ProteinInsight.AddVP(ProteinInsight.PDBs[0].GetChains("A"), IProteinInsight.IDisplayStyle.Ribbon);
            IVP VP2 = ProteinInsight.AddVP(ProteinInsight.PDBs[0].GetChains("B"), IProteinInsight.IDisplayStyle.BallnStick);

            VP1.PropertyRibbon.Helix.Color = Color.Red;
            VP2.Property.ColorScheme = IProperty.IColorScheme.Residue;

            for (Double degree = 0; degree < 360.0f; degree += 5.0)
            {
                Double radius = 30.0f;
                Double xPos = radius * Math.Cos(Math.PI * degree / 180.0);
                Double zPos = radius * Math.Sin(Math.PI * degree / 180.0);
                ProteinInsight.Property.Camera.Position = new Vector3((float)xPos, 0, (float)zPos);

                ProteinInsight.Idle(10);
            }

            ProteinInsight.SaveImage("1NME.png", 800, 600, IProteinInsight.IImageFormat.PNG);

        }

        public void test5(IProteinInsight ProteinInsight)
        {
            ProteinInsight.Open("1a31");             // Load Protein ID 1a31

            ProteinInsight.DeleteVP(ProteinInsight.VPs[0]);
            ProteinInsight.Property.ShowSelectionMark = false;
            ProteinInsight.Property.Background.Color = Color.White;
            ProteinInsight.Property.Background.ShowTexture = false;

            IVP vp1 = ProteinInsight.AddVP(ProteinInsight.PDBs[0].GetChains("A"), IProteinInsight.IDisplayStyle.Surface);
            IVP vp2 = ProteinInsight.AddVP(ProteinInsight.PDBs[0].GetChains("A"), IProteinInsight.IDisplayStyle.Ribbon);
            vp1.Property.Clippings[0].Enable = true;                            //  Turn on clipping plane  
            vp1.Property.Clippings[0].Transparency = 20;
            vp1.Property.Clippings[0].Color = Color.Red;

            vp1.MoveCenter();

            vp2.PropertyRibbon.Helix.ShowTexture = false;
            vp2.PropertyRibbon.Helix.Color = System.Drawing.Color.FromArgb(100, 0, 0);
            vp2.PropertyRibbon.Helix.Size = new System.Drawing.Size(80, 80);

            String strEqu2 = "0,-1,0,5";							//    Make clipping plane equation
            vp1.Property.Clippings[0].Equation = strEqu2;        //    Set new equation

            for (float height = 20.0f; height > -20.0f; height -= 4.3f)
            {
                String strEqu;
                strEqu = String.Format("0, -1, 0, {0:f}", height);           //    Make clipping plane equation
                vp1.Property.Clippings[0].Equation = strEqu;                 //    Set new equation
            }

        }

        public void test10(IProteinInsight ProteinInsight)
        {
            ProteinInsight.Open("1a6d");

            ProteinInsight.Property.RenderQuality.Shader = IRenderQuality.IShader.High;
            ProteinInsight.Property.RenderQuality.Geometry = IRenderQuality.IGeometry.High;
            ProteinInsight.Property.Lights[0].Show = false;

            IVP VP1 = ProteinInsight.AddVP(ProteinInsight.PDBs[0].GetChains("A"), IProteinInsight.IDisplayStyle.Ribbon);
            IVP VP2 = ProteinInsight.AddVP(ProteinInsight.PDBs[0].GetChains("A"), IProteinInsight.IDisplayStyle.Surface);
            IVP VP3 = ProteinInsight.AddVP(ProteinInsight.PDBs[0].GetChains("B"), IProteinInsight.IDisplayStyle.BallnStick);

            VP1.PropertyRibbon.Helix.Color = Color.Red;

            VP2.Property.ColorScheme = IProperty.IColorScheme.Residue;

            ProteinInsight.Property.Camera.Position = new Vector3(-50, 0, -80);

            ProteinInsight.SaveImage("1a6d.png", 800, 600, IProteinInsight.IImageFormat.PNG);
        }

        public void test7(IProteinInsight ProteinInsight)
        {
            ProteinInsight.Open("1t1k");

            ProteinInsight.Movie.BeginMovie("d:\\nmr_ani.wmv", 800, 600, 1, IMovie.ICaptureSource.PI ); 
            ProteinInsight.Property.Background.ShowTexture = false;
            ProteinInsight.Property.Background.Color = Color.White;
            ProteinInsight.Property.RenderQuality.Shader = IRenderQuality.IShader.High;
            ProteinInsight.Property.RenderQuality.Geometry = IRenderQuality.IGeometry.High;

            ProteinInsight.Property.ShowSelectionMark = false;

            ProteinInsight.DeleteVP(ProteinInsight.VPs[0]);

            foreach (IModel model in ProteinInsight.PDBs[0].Models)
            {
                IVP s = ProteinInsight.AddVP(model, IProteinInsight.IDisplayStyle.Ribbon);
                s.Show = false;
            }

            ProteinInsight.VPs[0].Show = true;

            ProteinInsight.Movie.Capture(1);

            for (int i = 1; i < ProteinInsight.VPs.Count; i++)
            {
                ProteinInsight.VPs[i].Show = true;
                ProteinInsight.VPs[i - 1].Show = false;
                ProteinInsight.Movie.Capture(1);
            }

            //	display surface method.
            ProteinInsight.Property.Camera.Position = new Vector3(0, 0, -100);

            foreach (IVP selection in ProteinInsight.VPs)
            {
                selection.Show = false;
                selection.DisplayStyle = IProteinInsight.IDisplayStyle.Surface;
            }

            ProteinInsight.VPs[0].Show = true;
            ProteinInsight.Movie.Capture(1);
            for (int i = 1; i < ProteinInsight.VPs.Count; i++)
            {
                ProteinInsight.VPs[i].Show = true;
                ProteinInsight.VPs[i - 1].Show = false;
                ProteinInsight.Movie.Capture(1);
            }

            ProteinInsight.Movie.EndMovie();
        }

        public void test11(IProteinInsight ProteinInsight)
        {
            Microsoft.DirectX.Direct3D.Surface rt = ProteinInsight.Utility.GetDirect3DDevice9().GetRenderTarget(0);

            ProteinInsight.Open("D:\\Postdoc\\ProteinVistaVer2\\ProteinInsight\\Bin\\DownloadPDB\\1dgc.ent");

            IChain chain4 = ProteinInsight.PDBs[3].Chains[0];

            IVP sel1 = ProteinInsight.AddVP(chain4, IProteinInsight.IDisplayStyle.Surface);

            sel1.Property.Clippings[0].Enable = true;
            sel1.Property.Clippings[0].Equation = "0,-1,0,3";

            Matrix rotX = new Matrix();
            Matrix rotY = new Matrix();
            //  float angle = 0.5f;
            Vector3 vecEye = new Vector3(0, 0, -90);

            //ProteinInsight.Property.Camera.Position = vecEye;
            //ProteinInsight.OutputMsg(ProteinInsight.Property.Camera.Position.ToString());

            //vecEye = ProteinInsight.Property.Camera.Position;
            //ProteinInsight.Property.Camera.Position = vecEye;

            //ProteinInsight.OutputMsg(ProteinInsight.Property.Camera.Position.ToString());

            //    sel1.Property.Clippings[0].Direction = !sel1.Property.Clippings[0].Direction;

            //  bool bBoolean = true;
            for (float height = 10.0f; height > -20.0f; height -= 1.05f)
            {
                Vector3 vecNormal = new Vector3(0, 1, 0);
                vecNormal.Normalize();

                sel1.Property.Clippings[0].Equation = String.Format("{0},{1},{2},{3}", vecNormal.X, vecNormal.Y, vecNormal.Z, height);
                sel1.Property.Clippings[0].Transparency = 50;

                rotX.RotateX(0.03f);
                rotY.RotateY(0.03f);

                vecEye.TransformCoordinate(rotY);
                //    sel1.RotationX(0.1f);

                String str = ProteinInsight.Property.Camera.Position.ToString();
                ProteinInsight.Utility.OutputMsg(str);

                Vector3 posCamera = ProteinInsight.Property.Camera.Position;

                //    ProteinInsight.Property.Lights[0].Enable = !(ProteinInsight.Property.Lights[0].Enable);

                //    Vector3 vecTemp = new Vector3(0, 40, 0); //   (ProteinInsight.Property.Camera.Position);
                //    ProteinInsight.Property.Camera.Position = vecTemp;

                //    ProteinInsight.Property.Camera.Position = posCamera;
            }
        }

        public void test8(IProteinInsight ProteinInsight)
        {
            ProteinInsight.Open("D:\\Postdoc\\ProteinVistaVer2\\ProteinInsight\\Bin\\DownloadPDB\\1dgc.ent");

            IChain chain4 = ProteinInsight.PDBs[3].Chains[0];

            IVP sel1 = ProteinInsight.AddVP(chain4, IProteinInsight.IDisplayStyle.Surface);
            ProteinInsight.AddVP(chain4, IProteinInsight.IDisplayStyle.Ribbon);

            for (int i = 0; i < 10; i++)
                sel1.Move(0.2f, 0, 0);
        }

        public void test9(IProteinInsight ProteinInsight)
        {
            ProteinInsight.Movie.BeginMovie("test1.wmv", 800, 600, 10, IMovie.ICaptureSource.PI );
            ProteinInsight.Open("D:\\Postdoc\\ProteinVistaVer2\\ProteinInsight\\Bin\\DownloadPDB\\1d66.ent");
            ProteinInsight.Movie.Capture(5);

            ProteinInsight.AddPDB("D:\\Postdoc\\ProteinVistaVer2\\ProteinInsight\\Bin\\DownloadPDB\\1dgc.ent");
            ProteinInsight.Movie.Capture(5);

            IPDB pdb2 = ProteinInsight.PDBs[0];

            ProteinInsight.SetSelect(false, true);

            ProteinInsight.Movie.Capture(5);
            ProteinInsight.SaveImage("t4.png", 800, 600, IProteinInsight.IImageFormat.PNG);

            IChain chain2 = ProteinInsight.PDBs[0].Chains[2];
            IChain chain3 = ProteinInsight.PDBs[0].Chains[3];
            chain2.SetSelect(true, true);

            ProteinInsight.Idle(1000.0f);

            IVP selection2 = ProteinInsight.AddVP(IProteinInsight.IDisplayStyle.Ribbon);
            IVP selection3 = ProteinInsight.AddVP(IProteinInsight.IDisplayStyle.Surface);

            ProteinInsight.Movie.Capture(5);

            for (int i = 1; i <= 100; i++)
            {
                selection3.PropertySurface.Transparency = i;
                ProteinInsight.Movie.Capture(1);
            }

            ProteinInsight.Movie.Capture(5);

            selection2.Property.Name = "Name Changed";
            //selection2.Property.AnnotationShow = true;
            //selection2.Property.AnnotationName = "test1";
            //selection2.Property.AnnotationColor = Color.Red;
            //  selection2.Property.AnnotationPosition = IProperty.IAnnotationPosition.Center;

            //    selection2.Property.Clipping1 = true;

            ProteinInsight.Movie.Capture(5);

            foreach (IVP selection in ProteinInsight.VPs)
            {
                selection.Show = false;
                ProteinInsight.Movie.Capture(5);
            }

            ProteinInsight.Movie.Capture(5);

            selection2.Show = true;

            ProteinInsight.Movie.Capture(5);

            ProteinInsight.SetSelect(false, true);
            chain2.SetSelect(true, true);

            ProteinInsight.Movie.Capture(5);

            foreach (IAtom atom in selection2.Atoms)
            {
                if (atom.Name == "CA")
                {
                    atom.SetSelect(true, false);
                }
                else
                {
                    atom.SetSelect(false, false);
                }
            }

            ProteinInsight.UpdateSelect();

            ProteinInsight.Movie.Capture(5);

            ProteinInsight.AddVP(IProteinInsight.IDisplayStyle.SpaceFill);

            ProteinInsight.Movie.Capture(5);

            ProteinInsight.Movie.EndMovie();

            //  enum type test.
            //    IHelixType type = (IHelixType)chain.Residues[0].HelixType;
            //    MessageBox.Show(type.ToString());

            //    ProteinInsight.ClosePDB(pdb);

            //    MessageBox.Show("Close Workspace");
            //    ProteinInsight.CloseWorkspace();

            /*
            IScribbleDoc scribDoc = iScribApp.GetDocument();
            IPDB pdb = scribDoc.GetPDB();
            scribDoc.AddChain();

            pdb.weight = 3;
            int test1 = pdb.weight;
            pdb.arrayListChains[0].m_strChainID = "test1";
            foreach (IChain chain in pdb.arrayListChains)
            {
                MessageBox.Show(chain.m_strChainID);
            }

            //  scribDoc.DrawLine(new Point(100,100), new Point(200,100));
             */


            //    ColorDialog colorChooser = new ColorDialog();
            //    if (colorChooser.ShowDialog() == DialogResult.OK){}
        }

        public void test12(IProteinInsight ProteinInsight)
        {
            ProteinInsight.Open("D:\\Postdoc\\ProteinVistaVer2\\ProteinInsight\\Bin\\DownloadPDB\\1dgc.ent");

            IPDB pdb = ProteinInsight.PDBs[3];

            Microsoft.DirectX.Matrix trI = Microsoft.DirectX.Matrix.Identity;
            Microsoft.DirectX.Matrix tr= pdb.TransformLocal;
            tr.M41++;
            pdb.TransformLocal = tr;
        }

        public void test23(IProteinInsight pi)
        {
            pi.Open("1a31");

            Matrix RotY = Matrix.RotationY(0.01F);
            for (int count = 0; count < 600; count++)
            {
                pi.Property.Camera.Position = Vector3.TransformCoordinate(pi.Property.Camera.Position, RotY);
                //  if (bMakeMovie == true) pi.Movie.Capture(1);
                pi.VPs[0].RotationY((float)((1 / 360.0f) * 2 * 3.14));
            }

        }
    }
}
